﻿using System;
using System.Collections.Generic;
using System.Data.Entity;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace MvcBoost.EntityFramework.Validation
{
    public class CheckValidatorBase<TContext, TResource> : IDbContextResourceValidator<TContext, TResource>
        where TContext : DbContext
        where TResource : class
    {
        public CheckValidatorBase( Func<TContext,TResource, bool> validation, bool checkWhenCreating, bool checkWhenEditing) 
        {
            if (validation == null) throw new ArgumentNullException("Invalid validation expressión");
            Validation = validation;
            CheckWhenCreating = checkWhenCreating;
            CheckWhenEditing = checkWhenEditing;
        }

        public Func<TContext, TResource, bool> Validation { get; private set; }
        public bool CheckWhenCreating { get; protected set; }
        public bool CheckWhenEditing { get; protected set; }

        public bool IsValid(TContext context, TResource resource, bool isCreating)
        {
            if ((isCreating) && (CheckWhenCreating)) return Validation(context, resource);
            if ((!isCreating) && (CheckWhenEditing)) return Validation(context, resource);
            throw new InvalidOperationException("This validation will never be activated");
        }

        public string ValidationMessage { get; protected set; }

        public IDbContextResourceValidator<TContext, TResource> SetValidationMessage(string message)
        {
            this.ValidationMessage = message;
            return this;
        }

        public virtual bool Matches(TContext context, TResource resource, bool isCreating)
        {
            return true;
        }
    }

    public class CheckWhenCreatingValidator<TContext, TResource> : CheckValidatorBase<TContext, TResource>
        where TContext : DbContext
        where TResource : class
    {
        public CheckWhenCreatingValidator(Func<TContext, TResource, bool> validation)
            : base(validation, true, false)
        {
        }
    }

    public class CheckWhenEditingValidator<TContext, TResource> : CheckValidatorBase<TContext, TResource>
        where TContext : DbContext
        where TResource : class
    {
        public CheckWhenEditingValidator(Func<TContext, TResource, bool> validation)
            : base(validation, false, true)
        {
        }
    }

    public class CheckWhenCreatingAndEditingValidator<TContext, TResource>: CheckValidatorBase<TContext,TResource>
        where TContext : DbContext
        where TResource : class
    {
        public CheckWhenCreatingAndEditingValidator(Func<TContext, TResource, bool> validation)
            : base(validation, true, true)
        {
        }        
    }
}
